package com.ccc.hotsearch.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ccc.hotsearch.model.HotItem;
import com.ccc.hotsearch.model.PlatformTypeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class WeiboHotSearchServiceImpl implements HotSearchService {
    protected static final Logger logger = LoggerFactory.getLogger(WeiboHotSearchServiceImpl.class);

    private static final String REALTIME_URL = "https://weibo.com/ajax/side/hotSearch";

    @Override
    public PlatformTypeEnum getPlatformType() {
        return PlatformTypeEnum.WEIBO;
    }

    @Override
    public List<HotItem> getHotSearch() {
        return getHotSearchFromAPI();
    }

    private List<HotItem> getHotSearchFromAPI() {
        List<HotItem> items = new ArrayList<>();

        try {
            HttpRequest request = HttpUtil.createGet(REALTIME_URL)
                    .header("User-Agent", getRandomUserAgent())
                    .header("Referer", "https://weibo.com/")
                    .header("Accept", "application/json")
                    .header("Cookie", "SUB=_2A25IUXXXDeRhGeNK6lAZ-CvKyz-IHXVqkPXbrDV6PUJbktAGLUXlkW1NQTyok5Q7wUG5S5B-2o_71K4W4S5sxRgU;")
                    .timeout(10000);

            HttpResponse response = request.execute();

            if (response.isOk()) {
                String json = response.body();
                items = parseApiData(json);
            }

            TimeUnit.MILLISECONDS.sleep(500);

        } catch (Exception e) {
            logger.error("【捕获异常-微博API请求失败】\r\n异常记录：", e);
        }

        return items;
    }

    private List<HotItem> parseApiData(String json) {
        List<HotItem> normalItems = new ArrayList<>(); // 普通热搜
        HotItem pinnedItem = null; // 置顶热搜

        try {
            JSONObject jsonObject = JSONUtil.parseObj(json);

            if (jsonObject.getInt("ok", 0) != 1) {
                return new ArrayList<>();
            }

            JSONObject data = jsonObject.getJSONObject("data");
            if (data == null) {
                return new ArrayList<>();
            }

            // 1. 首先处理置顶热搜 (hotgov)
            JSONObject hotgov = data.getJSONObject("hotgov");
            if (hotgov != null) {
                pinnedItem = parsePinnedItem(hotgov);
            }

            // 2. 处理普通热搜列表 (realtime)
            JSONArray realtime = data.getJSONArray("realtime");
            if (realtime != null) {
                for (int i = 0; i < realtime.size(); i++) {
                    try {
                        JSONObject item = realtime.getJSONObject(i);
                        HotItem hotItem = parseNormalItem(item, i);
                        if (hotItem != null) {
                            normalItems.add(hotItem);
                        }
                    } catch (Exception e) {
                        logger.error("【解析第 " + (i + 1) + " 条微博热搜失败】\r\n异常记录：", e);
                    }
                }
            }

            // 3. 合并结果：置顶热搜 + 普通热搜
            List<HotItem> allItems = new ArrayList<>();

            // 如果有置顶热搜，放在第一个位置
            if (pinnedItem != null) {
                allItems.add(pinnedItem);
                System.out.println("找到置顶热搜: " + pinnedItem.getTitle());
            }

            // 添加普通热搜（按热度倒序）
            allItems.addAll(sortByHotValue(normalItems));

            // 4. 重新设置排名
            for (int i = 0; i < allItems.size(); i++) {
                allItems.get(i).setRank(String.valueOf(i + 1));
            }

            return allItems;
        } catch (Exception e) {
            logger.error("【捕获异常-解析微博API数据失败】\r\n异常记录：", e);
            return new ArrayList<>();
        }
    }
    /**
     * 解析置顶热搜
     */
    private HotItem parsePinnedItem(JSONObject hotgov) {
        try {
            String title = hotgov.getStr("word");
            String note = hotgov.getStr("note", "");
            String tag = hotgov.getStr("icon_desc", "热");

            if (StrUtil.isBlank(title)) {
                return null;
            }

            // 使用现有的HotItem结构
            HotItem pinnedItem = HotItem.create(PlatformTypeEnum.WEIBO, "0", title, "9999999"); // 置顶热度设为最高
            pinnedItem.setTag(tag);
            pinnedItem.setDescription("置顶热搜 - " + note);
            pinnedItem.setAd(false);
            pinnedItem.setTagColor(getTagColor(tag));

            // 在description中包含置顶信息，方便前端识别
            pinnedItem.setDescription("【置顶】" + note);

            // 设置URL
            String url = generateWeiboUrl(title, title);
            pinnedItem.setUrl(url);

            return pinnedItem;

        } catch (Exception e) {
            System.err.println("解析置顶热搜失败: " + e.getMessage());
            return null;
        }
    }

    /**
     * 解析普通热搜项
     */
    private HotItem parseNormalItem(JSONObject item, int index) {
        try {
            String rank = String.valueOf(index + 1);
            String title = item.getStr("word");
            String hotValue = item.getStr("num", "0");
            String tag = item.getStr("label_name", "");
            String note = item.getStr("note", "");
            String wordScheme = item.getStr("word_scheme", "");

            // 跳过空标题
            if (StrUtil.isBlank(title)) {
                return null;
            }

            HotItem hotItem = HotItem.create(PlatformTypeEnum.WEIBO, rank, title, hotValue);
            hotItem.setTag(tag);
            hotItem.setDescription(note);
            hotItem.setAd("广告".equals(tag) || item.getBool("is_ad", false));
            hotItem.setTagColor(getTagColor(tag));

            // 设置URL
            String url = generateWeiboUrl(title, wordScheme);
            hotItem.setUrl(url);

            return hotItem;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 按热度值倒序排序
     */
    private List<HotItem> sortByHotValue(List<HotItem> items) {
        items.sort((a, b) -> {
            try {
                int hotA = Integer.parseInt(a.getHotValue());
                int hotB = Integer.parseInt(b.getHotValue());
                return Integer.compare(hotB, hotA); // 倒序
            } catch (NumberFormatException e) {
                return 0;
            }
        });
        return items;
    }

    /**
     * 生成微博搜索URL
     */
    private String generateWeiboUrl(String title, String wordScheme) {
        try {
            String searchKeyword = title;
            // 如果有话题格式，使用话题格式
            if (StrUtil.isNotBlank(wordScheme) && wordScheme.startsWith("#") && wordScheme.endsWith("#")) {
                searchKeyword = wordScheme;
            }
            String encodedKeyword = URLEncoder.encode(searchKeyword, StandardCharsets.UTF_8.name());
            return "https://s.weibo.com/weibo?q=" + encodedKeyword;
        } catch (Exception e) {
            return "https://s.weibo.com/weibo?q=" + title;
        }
    }

    private String getTagColor(String tag) {
        switch (tag) {
            case "爆":
                return "#ff3852";
            case "热":
                return "#ff9600";
            case "新":
                return "#00b4ff";
            case "沸":
                return "#ff3852";
            case "荐":
                return "#999999";
            default:
                return "#cccccc";
        }
    }

    private String getRandomUserAgent() {
        List<String> userAgents = CollUtil.newArrayList(
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0"
        );
        return RandomUtil.randomEle(userAgents);
    }
}
